package de.staxx6.bomber;

import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;

import de.staxx6.bomber.box.BombBox;

public class Player {
	
	private float x;
	private float y;
	private int playerNumber;
	private float playerSize = 0.45f;
	
	private int posX;
	private int posY;
	private float posXf;
	private float posYf;
	
	private String direction = "Down";
	private boolean isMoving = false;
	private float speed = 2.8f;
	private Field field;
	
	private BombBox bomb;
	
	private Node playerNode = new Node("Player Node");
	private Geometry player;
	CharacterControl charControl;
	
	private boolean isDead = false;
	
	public Player(float newX, float newY, final int newPlayerNumber, Field newField) {
		this.x = newX;
		this.y = newY;
		this.playerNumber = newPlayerNumber;
		this.field = newField;
		
		Box box_player = new Box(Vector3f.ZERO, 0.5f, 0.5f, 0.5f);
		player = new Geometry("Ground", box_player);
		Material mat_player = new Material(GameState.ASSETMANAGER, "Common/MatDefs/Misc/Unshaded.j3md");
		if(playerNumber == 1) {
			mat_player.setColor("Color", ColorRGBA.Blue);
			direction = "Up";
		} else if(playerNumber == 2) {
			mat_player.setColor("Color", ColorRGBA.Red);
			direction = "Down";
		} else if(playerNumber == 3) {
			mat_player.setColor("Color", ColorRGBA.Yellow);
			direction = "Down";
		} else {
			mat_player.setColor("Color", ColorRGBA.Green);
			direction = "Up";
		}
		player.setMaterial(mat_player);
		playerNode.attachChild(player);
		
		CylinderCollisionShape boxCollision = new CylinderCollisionShape(new Vector3f(playerSize, playerSize, playerSize));
		charControl = new CharacterControl(boxCollision, 0.0f);
		charControl.setGravity(0);
		playerNode.addControl(charControl);
		GameState.BULLETAPPSTATE.getPhysicsSpace().add(charControl);
		charControl.setPhysicsLocation(new Vector3f(x - 0.01f, y - 0.01f, 1.5f));

		initKeys();
		System.out.println("Player created@ X: " + x + " Y: " + y + " Number: " + playerNumber);
	}
	
	public void setDirection(final String newDirection) {
		this.direction = newDirection;
	}
	
	public void setIsMoving(final boolean newIsMoving) {
		this.isMoving = newIsMoving;
	}
	
	public void update(float delta) {
		Vector3f originalPos = new Vector3f(charControl.getPhysicsLocation());
		posX = (int) (originalPos.x + 0.5);
		posY = (int) (originalPos.y + 0.5);
		posXf = originalPos.x;
		posYf = originalPos.y;
		
		charControl.setWalkDirection(Vector3f.ZERO);
		if(isMoving) {
			if(direction.equals("Up")) {
				charControl.setWalkDirection(new Vector3f(0, speed * delta, 0));
			} else if(direction.equals("Down")) {
				charControl.setWalkDirection(new Vector3f(0, -(speed * delta), 0));
			}  else if(direction.equals("Left")) {
				charControl.setWalkDirection(new Vector3f(-(speed * delta), 0, 0));
			}  else if(direction.equals("Right")) {
				charControl.setWalkDirection(new Vector3f(speed * delta, 0, 0));
			}
		}
		isMoving = false;
		
		if(bomb != null) {
			for(int i = 0; i < field.boxList.size(); i++) {
				if(field.boxList.get(i) instanceof BombBox) {
					if(field.boxList.get(i).getPlayerNumber() == playerNumber) {
						((BombBox) field.boxList.get(i)).playerPosition(posXf, posYf);
					}
					if(((BombBox) field.boxList.get(i)).isExplode()) {
						field.boxList.remove(i); 
					}
				}
			}
		}
		/* Check for explosions */
		if(field.isExplosionBox(posX, posY)) {
			System.out.println("PLAYER " + playerNumber + " DIED!!!!!!!!!!!!!!!");
			isDead = true;
		}
	}
	
	public boolean isDead() {
		return isDead;
	}
	
	private void initKeys() {
		/* Player one */
		if(playerNumber == 1) {
			GameState.INPUTMANAGER.addMapping("1Up", new KeyTrigger(KeyInput.KEY_W));
			GameState.INPUTMANAGER.addMapping("1Down", new KeyTrigger(KeyInput.KEY_S));
			GameState.INPUTMANAGER.addMapping("1Left", new KeyTrigger(KeyInput.KEY_A));
			GameState.INPUTMANAGER.addMapping("1Right", new KeyTrigger(KeyInput.KEY_D));
			GameState.INPUTMANAGER.addMapping("1Bomb", new KeyTrigger(KeyInput.KEY_Q));
			GameState.INPUTMANAGER.addListener(analogListener, new String[] {"1Up", "1Down", "1Left", "1Right"});
			GameState.INPUTMANAGER.addListener(actionListener, new String[] {"1Bomb"});
		}
		/* Player two */
		if(playerNumber == 2) {
			GameState.INPUTMANAGER.addMapping("2Up", new KeyTrigger(KeyInput.KEY_UP));
			GameState.INPUTMANAGER.addMapping("2Down", new KeyTrigger(KeyInput.KEY_DOWN));
			GameState.INPUTMANAGER.addMapping("2Left", new KeyTrigger(KeyInput.KEY_LEFT));
			GameState.INPUTMANAGER.addMapping("2Right", new KeyTrigger(KeyInput.KEY_RIGHT));
			GameState.INPUTMANAGER.addMapping("2Bomb", new KeyTrigger(KeyInput.KEY_RCONTROL));
			GameState.INPUTMANAGER.addListener(analogListener, new String[] {"2Up", "2Down", "2Left", "2Right"});
			GameState.INPUTMANAGER.addListener(actionListener, new String[] {"2Bomb"});
		}
		/* Player three */
		if(playerNumber == 3) {
			GameState.INPUTMANAGER.addMapping("3Up", new KeyTrigger(KeyInput.KEY_I));
			GameState.INPUTMANAGER.addMapping("3Down", new KeyTrigger(KeyInput.KEY_K));
			GameState.INPUTMANAGER.addMapping("3Left", new KeyTrigger(KeyInput.KEY_J));
			GameState.INPUTMANAGER.addMapping("3Right", new KeyTrigger(KeyInput.KEY_L));
			GameState.INPUTMANAGER.addMapping("3Bomb", new KeyTrigger(KeyInput.KEY_N));
			GameState.INPUTMANAGER.addListener(analogListener, new String[] {"3Up", "3Down", "3Left", "3Right"});
			GameState.INPUTMANAGER.addListener(actionListener, new String[] {"3Bomb"});
		}
		/* Player four */
		if(playerNumber == 4) {
			GameState.INPUTMANAGER.addMapping("4Up", new KeyTrigger(KeyInput.KEY_NUMPAD5));
			GameState.INPUTMANAGER.addMapping("4Down", new KeyTrigger(KeyInput.KEY_NUMPAD2));
			GameState.INPUTMANAGER.addMapping("4Left", new KeyTrigger(KeyInput.KEY_NUMPAD1));
			GameState.INPUTMANAGER.addMapping("4Right", new KeyTrigger(KeyInput.KEY_NUMPAD3));
			GameState.INPUTMANAGER.addMapping("4Bomb", new KeyTrigger(KeyInput.KEY_ADD));
			GameState.INPUTMANAGER.addListener(analogListener, new String[] {"4Up", "4Down", "4Left", "4Right"});
			GameState.INPUTMANAGER.addListener(actionListener, new String[] {"4Bomb"});
		}
	}
	private ActionListener actionListener = new ActionListener() {
		@Override
		public void onAction(String name, boolean keyPressed, float delta) {
			if(playerNumber == 1 && name.equals("1Bomb") && !keyPressed) {
				placeBomb();
			}
			if(playerNumber == 2 && name.equals("2Bomb") && !keyPressed) {
				placeBomb();
			}
			if(playerNumber == 3 && name.equals("3Bomb") && !keyPressed) {
				placeBomb();
			}
			if(playerNumber == 4 && name.equals("4Bomb") && !keyPressed) {
				placeBomb();
			}
		}
	};
	
	private void placeBomb() {
		if(field.isPlace(posX, posY)) {
			System.out.println(" BOMB placing@ X:" + posX + " Y: " + posY);
			field.boxList.add(bomb = new BombBox(posX, posY, field.getNode(), field, playerNumber));
		}
	}
	
	private AnalogListener analogListener = new AnalogListener() {
		@Override
		public void onAnalog(String name, float value, float delta) {
			if(GameState.ISRUNNING) {
				/* No reset of isMoving required */
				/* Player one */
				isMoving = true;
				if(playerNumber == 1) {
					if(name.equals("1Up") && !name.equals("1Down")
							&& !name.equals("1Left") && !name.equals("1Right")) {
						direction = "Up";
					} else if(name.equals("1Down") && !name.equals("1Up")
							&& !name.equals("1Left") && !name.equals("1Right")) {
						direction = "Down";
					} else if(name.equals("1Left") && !name.equals("1Right")
							&& !name.equals("1Down") && !name.equals("1Right")) {
						direction = "Left";
					} else if(name.equals("1Right") && !name.equals("1Left")
							&& !name.equals("1Down") && !name.equals("1Up")) {
						direction = "Right";
					}
				}
				/* Player two */
				if(playerNumber == 2) {
					if(name.equals("2Up") && !name.equals("2Down")
							&& !name.equals("2Left") && !name.equals("2Right")) {
						direction = "Up";
					} else if(name.equals("2Down") && !name.equals("2Up")
							&& !name.equals("2Left") && !name.equals("2Right")) {
						direction = "Down";
					} else if(name.equals("2Left") && !name.equals("2Right")
							&& !name.equals("2Up") && !name.equals("2Down")) {
						direction = "Left";
					} else if(name.equals("2Right") && !name.equals("2Left")
							&& !name.equals("2Down") && !name.equals("2Up")) {
						direction = "Right";
					}
				}
				/* Player three */
				if(playerNumber == 3) {
					if(name.equals("3Up") && !name.equals("3Down")
							&& !name.equals("3Left") && !name.equals("3Right")) {
						direction = "Up";
					} else if(name.equals("3Down") && !name.equals("3Up")
							&& !name.equals("3Left") && !name.equals("3Right")) {
						direction = "Down";
					} else if(name.equals("3Left") && !name.equals("3Right")
							&& !name.equals("3Up") && !name.equals("3Down")) {
						direction = "Left";
					} else if(name.equals("3Right") && !name.equals("3Left")
							&& !name.equals("3Down") && !name.equals("3Up")) {
						direction = "Right";
					}
				}
				/* Player three */
				if(playerNumber == 4) {
					if(name.equals("4Up") && !name.equals("4Down")
							&& !name.equals("4Left") && !name.equals("4Right")) {
						direction = "Up";
					} else if(name.equals("4Down") && !name.equals("4Up")
							&& !name.equals("4Left") && !name.equals("4Right")) {
						direction = "Down";
					} else if(name.equals("4Left") && !name.equals("4Right")
							&& !name.equals("4Up") && !name.equals("4Down")) {
						direction = "Left";
					} else if(name.equals("4Right") && !name.equals("4Left")
							&& !name.equals("4Down") && !name.equals("4Up")) {
						direction = "Right";
					}
				}
			}
			
		}
	};
	
	public CharacterControl getPhysic() {
		return charControl;
	}
	
	public Node getNode() {
		return playerNode;
	}
}
